package cn.itcast.p2p20.ui;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

/**
 * Created by Administrator on 2016/7/29.
 */
public class RandomLayout extends FrameLayout {

    private static final String TAG = "RandomLayout";
    private static final int MAX_TRY_LAYOUT_COUNT = 30;


    public RandomLayout(Context context) {
        super(context);
    }

    public RandomLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public RandomLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int measuredWidth = getMeasuredWidth();
        int measuredHeight = getMeasuredHeight();

        int width = getWidth();
        int height = getHeight();

        Log.d(TAG, "onMeasure() called");


        super.onMeasure(widthMeasureSpec, heightMeasureSpec);


        int measuredWidth1 = getMeasuredWidth();
        int measuredHeight1 = getMeasuredHeight();

        int width1 = getWidth();
        int height1 = getHeight();

        //如果要通过layoutParams获取宽度或者高度控件的需要指定确定宽度和高度，
        //如果是MATCH_PARENT = -1; 得到的值是-1
        //如果是WRAP_CONTENT = -2; 得到是值是-2
        ViewGroup.LayoutParams layoutParams = getLayoutParams();
        int width2 = layoutParams.width;
        int height2 = layoutParams.height;

        Log.d(TAG, "onMeasure() called");
    }

    //onMeasure ---->onSizeChanged
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    }

    //计算面积，按照面积大小排序
    private static class ViewAreaBean implements Comparable<ViewAreaBean> {

        private View view;

        private int area;

        public ViewAreaBean(View view) {
            this.view = view;
            //计算面积
            area = view.getMeasuredWidth() * view.getMeasuredHeight();
        }

        //按照面积大小排序:从大到小
        @Override
        public int compareTo(ViewAreaBean another) {
            return -(this.area - another.area);
        }
    }


    private Random mRandom = new Random();

    private List<ViewAreaBean> mViewAreaBeans = new ArrayList<>();

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

        //重新摆放之前需要清空集合
        mLayoutedViews.clear();
        int measuredWidth = getMeasuredWidth();
        int measuredHeight = getMeasuredHeight();
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {

            mViewAreaBeans.add(new ViewAreaBean(getChildAt(i)));
        }
        //排序
        Collections.sort(mViewAreaBeans);


        for (ViewAreaBean viewAreaBean : mViewAreaBeans) {

            View childView = viewAreaBean.view;
            int childViewMeasuredWidth = childView.getMeasuredWidth();
            int childViewMeasuredHeight = childView.getMeasuredHeight();
            //摆放

            //不断去尝试摆放
            int tryLayoutCount = MAX_TRY_LAYOUT_COUNT;
            while (tryLayoutCount-- > 0) {

                //如果在尝试的时候摆放成功应该跳出循环
                if (tryLayout(measuredWidth, measuredHeight, childView, childViewMeasuredWidth, childViewMeasuredHeight)) {

                    break;
                }
            }

            //如果尝试摆放30次都失败了，那么控件会回到原来的位置，会出现重叠
            if (tryLayoutCount <= 0) {

                Log.d(TAG, ((TextView) childView).getText().toString() + " 摆放失败");
                childView.layout(-1, -1, -1, -1);
            }
        }

        //onLayout ----> setFrame ---  public final int getWidth() {
        //          return mRight - mLeft;

        //getWidth ,getHeight 能够获取确定的值需要的layout调用之后

//        int width1 = getWidth();
//        int height1 = getHeight();

        Log.d(TAG, "onLayout() called");
    }

    private List<View> mLayoutedViews = new ArrayList<>();

    //根据随机的位置尝试去摆放
    private boolean tryLayout(int measuredWidth, int measuredHeight, View childView, int childViewMeasuredWidth, int childViewMeasuredHeight) {

        //随机分配的一个摆放的位置
        int childViewLeft = mRandom.nextInt(measuredWidth - childViewMeasuredWidth > 0 ? measuredWidth - childViewMeasuredWidth : 1);
        int childViewTop = mRandom.nextInt(measuredHeight - childViewMeasuredHeight > 0 ? measuredHeight - childViewMeasuredHeight : 1);
        int childViewRight = childViewLeft + childViewMeasuredWidth;
        int childViewBottom = childViewTop + childViewMeasuredHeight;

        //对这个位置进行判断，childViewLeft，childViewTop，childViewRight，childViewBottom
        //这个矩形和已经摆放的所有的矩形是否有交点
        if (canLayout(childViewLeft, childViewTop, childViewRight, childViewBottom)) {

            childView.layout(childViewLeft, childViewTop, childViewRight, childViewBottom);
            //摆放成功，将摆放成功的view添加到一个集合
            mLayoutedViews.add(childView);
            return true;
        } else {

            return false;
        }
    }

    private Rect outRect = new Rect();
    ;

    //判断当前的矩形和所有其他的矩形是否有交点
    private boolean canLayout(int childViewLeft, int childViewTop, int childViewRight, int childViewBottom) {

        for (View view : mLayoutedViews) {

            //获取控件在当前的父控件里面的矩形位置
            view.getHitRect(outRect);
            //判断两个矩形是否有交点
            if (outRect.intersect(childViewLeft, childViewTop, childViewRight, childViewBottom)) {

                return false;
            }
        }
        return true;
    }
}
